import AirTicketServer from './air-ticket-server';
import { memoize } from 'lodash';
import { regTypeMap, formatSequence, MonthTransform, parseKeyMap, typeNum } from './airline-parser-config';

const findAllIndexs = (ary, item) => {
    const ret = [];
    for (let i = 0; i < ary.length; i++) {
        if (ary[i] === item) {
            ret.push(i);
        }
    }
    return ret;
}

export const specialDuplicateRemoval = ary => {
    const retAry = ary.slice();
    for (let idx = 0; idx < ary.length; idx++) {
        const item = ary[idx];
        if (typeof item === "string") {
            const duplicateList = findAllIndexs(retAry.slice(idx + 1), item);
            for (let i = 0; i < duplicateList.length; i++) {
                const duplicateIdx = duplicateList[i];
                retAry[duplicateIdx + idx + 1] = idx;
            }
        }
    }
    return retAry;
}

const transformAirports = async airports => {
    const getAirport = AirTicketServer(this).ariportSearch;
    const airportsProcessed = specialDuplicateRemoval(airports);

    const getAirportPromises = airportsProcessed.map(airport => typeof airport === "string" ? (airport === "empty" ? Promise.resolve(null) : getAirport(airport)) : Promise.resolve(airport));
    const airportResults = await Promise.all(getAirportPromises).catch(err => { console.log(err) });
    const airportCodeEqual = idx => ({ airportCode }) => airportCode === airportsProcessed[idx];

    const feedbackResult = (res, idx) => {
        let airportDatas;

        if (typeof res === "number") {
            const dataRes = airportResults[res];

            if (!dataRes) {
                return;
            }
            airportDatas = dataRes.data;
            const airportResByNumber = airportDatas.filter(airportCodeEqual(res))[0];
            return airportResByNumber;
        } else {
            if (res) {
                airportDatas = res.data;
                const airportRes = airportDatas.filter(airportCodeEqual(idx))[0];
                return airportRes;
            } else {
                return;
            }
        }
    }

    const airportResultDatas = airportResults.map(feedbackResult);
    return airportResultDatas;
}

const getAirline = async airline => {
    if (!airline) {
        return null;
    }

    airline = airline.slice(0, 2);
    const airlines = await AirTicketServer(this).airlineSearch(airline).catch(err => { });
    const retAirlines = airlines.data.filter(item => item.code === airline);
    return retAirlines[0] ? retAirlines[0] : null;
}

//缓存化机场转换函数
export const cacheTransformAirports = memoize(transformAirports, airports => airports.join());

export const cacheGetAirline = memoize(getAirline);

//排除项
const excludes = [""];
export const lineSpliter = content => content.split('\n').filter(item => !excludes.includes(item));
export const segTokenizer = seg => seg.split(/\s+/).filter(item => !excludes.includes(item));

export const tokenMap = values => {
    const retObj = {};
    values.forEach((value, idx) => { 
        retObj[parseKeyMap[idx]] = value;
        if(parseKeyMap[idx] === "airportNames"){
            retObj.departureAirportName = value.slice(0,3);
            retObj.arrivalAirportName = value.slice(3,6);
        }
    });
    return retObj;
}

export const feedbackAirportList = (pre, cur) => pre.concat([cur.departureAirportName, cur.arrivalAirportName]);

export const parseDateDetail = (timeDetail, depatureTime, arrivalTime) => {
    if (!timeDetail) {
        return {}
    }
    let isCrossDays = false;
    if (depatureTime && arrivalTime && arrivalTime.indexOf("+") >= 0) {
        isCrossDays = !isCrossDays;
    }

    const year = new Date().getFullYear();
    const month = MonthTransform[timeDetail.match(/[a-zA-Z]{3}/g)[0]]
    let day = timeDetail.match(/\d+/g)[0];

    const date = `${year}-${month}-${day}`;
    let depTime = depatureTime && depatureTime.split('');
    let arrTime = arrivalTime && arrivalTime.split("+")[0].split('');
    let addDays = arrivalTime && Number(arrivalTime.split("+")[1]);
    if (depTime) {
        if (Number(depTime.slice(0, 2).join("")) > 24 && depTime.length === 3) {
            depTime.splice(1, 0, ":");
        } else {
            depTime.splice(2, 0, ":");
        }
    }


    if (arrTime) {
        if (Number(arrTime.slice(0, 2).join("")) > 24 && arrTime.length === 3) {
            arrTime.splice(1, 0, ":");
        } else {
            arrTime.splice(2, 0, ":");
        }
    }

    depTime = depTime ? depTime.join('') : '';
    arrTime = arrTime ? arrTime.join('') : '';
    return { departureDate: `${date} ${depTime}`, arrivalDate: `${date} ${arrTime}`, isCrossDays , addDays}
}

const tokenTypes = token => {
    const type = Object.entries(regTypeMap).filter(([type, reg]) => {
        return reg.test(token);
    });
    return type.length ? type.map(item => item[0]) : false;
}

//格式是否正确
export const isFormatCorrect = segInfos => {
    return !!(segInfos.length === 8 && formatSequence.reduce((pre, cur, idx) => {
        if (idx === 5) {
            return true && pre;
        } else {
            return tokenTypes(segInfos[idx]) && tokenTypes(segInfos[idx]).includes(cur) && pre
        }
    }, true))
}

export const isFormatCorrects = segInfos => {
    for(let i = 0; i< segInfos.length;i++){
        if(!isFormatCorrect(segInfos[i])){
            return false;
        }
    }
        
    return true;
}

//模糊映射
export const fuzzyTransformSegInfo = segInfos => {
    const retObj = {};
    const slicedRetObj = {};
    const finalRetObj = {};

    segInfos.forEach( (item,idx) => {
        const type = tokenTypes(item);
        if (type) {
            (retObj[type[0]] && retObj[type[0]].push(item)) || (retObj[type[0]] = [item])
        }

        if(item === "SEAME"){
            finalRetObj.departureTerminal = `T${segInfos[idx+1]}`;
            finalRetObj.arrivalTerminal = `T${segInfos[idx+2]}`;
        }
    })

    //得出的retObj是类型分组的结构,类似于这样{time:["1122","1133"],airport:["zxz","aaa"]}
    //接下去对各个类型的数据做分割
    Object.keys(retObj).forEach(item => {
        slicedRetObj[item] = retObj[item].slice(0, typeNum[item]);
    })

    if(slicedRetObj.airport){
        finalRetObj.departureAirportName = slicedRetObj.airport[0].slice(0,3);
        finalRetObj.arrivalAirportName = slicedRetObj.airport[0].slice(3,6);
    }else{
        finalRetObj.departureAirportName = (slicedRetObj.airportFuzzy && slicedRetObj.airportFuzzy[0]) || "empty";
        finalRetObj.arrivalAirportName = (slicedRetObj.airportFuzzy && slicedRetObj.airportFuzzy[1]) || "empty";
    }

    finalRetObj.depatureTime = (slicedRetObj.time && slicedRetObj.time[0]) || null;
    finalRetObj.arrivalTime = (slicedRetObj.time && slicedRetObj.time[1]) || null;
    delete slicedRetObj.airport;
    delete slicedRetObj.time;
    delete slicedRetObj.airportFuzzy;

    Object.keys(slicedRetObj).forEach(item => {
        finalRetObj[item] = slicedRetObj[item][0];
    })

    return finalRetObj;
}